
#include "Header.h"
#include "FilterEQFast.h"
#include <math.h>


struct Equalizer2DataStruct
{
	int Channels;
	int Length;
} typedef Equalizer2Data;

class Equalizer2Ptr
{
	FilterEQFast* mEQ;
	int mEQCount;
	double mBand1 = 1;
	double mBand2 = 1;
	double mBand3 = 1;
	double mLowFrequency;
	double mHighFrequency;
	int mSampleRate;

public:

	Equalizer2Ptr()
	{
		// Minimum 1 size. Otherwise the Low/HighFrequency properties will crash.
		mEQCount = 1;
		mEQ = new FilterEQFast[1];
	}
	~Equalizer2Ptr()
	{
		if (mEQ != 0)
		{
			delete[] mEQ;
		}
	}

	void SetBand1(double value)
	{
		mBand1 = value;
		for (int i = 0; i < mEQCount; i++)
		{
			mEQ[i].low_volyme = value;
		}
	}

	void SetBand2(double value)
	{
		mBand2 = value;
		for (int i = 0; i < mEQCount; i++)
		{
			mEQ[i].mid_volyme = value;
		}
	}

	void SetBand3(double value)
	{
		mBand3 = value;
		for (int i = 0; i < mEQCount; i++)
		{
			mEQ[i].hi_volyme = value;
		}
	}

	void SetLowFrequency(double value)
	{
		mLowFrequency = value;
		for (int i = 0; i < mEQCount; i++)
		{
			mEQ[i].Frequency = value;
			mEQ[i].Init();
		}
	}

	void SetHighFrequency(double value)
	{
		mHighFrequency = value;
		for (int i = 0; i < mEQCount; i++)
		{
			mEQ[i].Q = value;
			mEQ[i].Init();
		}
	}

	void SetOutputChannels(int channels, int sampleRate)
	{
		if (mEQCount != channels || mSampleRate != sampleRate)
		{
			// Minimum 1 size allowed.
			channels = fmax(1, channels);

			if (channels > mEQCount)
			{
				delete[] mEQ;
				mEQ = new FilterEQFast[channels];
			}

			mEQCount = channels;
			mSampleRate = sampleRate;

			for (int i = 0; i < mEQCount; i++)
			{
				FilterEQFast& eq = mEQ[i];
				eq.Reset();

				eq.SampleRate = sampleRate;
				eq.low_volyme = mBand1;
				eq.mid_volyme = mBand2;
				eq.hi_volyme = mBand3;
				eq.Frequency = mLowFrequency;
				eq.Q = mHighFrequency;
				eq.Init();
			}
		}
	}

	void Update(int sampleRate, int outputChannels, double lowFrequency, double highFrequency, double band1, double band2, double band3)
	{
		SetOutputChannels(outputChannels, sampleRate);
		SetLowFrequency(lowFrequency);
		SetHighFrequency(highFrequency);
		SetBand1(band1);
		SetBand2(band2);
		SetBand3(band3);
	}

	void Process(Equalizer2Data* data, double* audioBufferLeft, double* audioBufferRight, double* audioBufferLeft_output, double* audioBufferRight_output)
	{
		for (int c = 0; c < data->Channels; c++)
		{
			double* inputSamples = c == 0 ? audioBufferLeft : audioBufferRight;
			double* outputSamples = c == 0 ? audioBufferLeft_output : audioBufferRight_output;
			mEQ[c].ProcessTime(inputSamples, outputSamples, data->Length);
		}
	}
};

extern "C"
{
	DECLSPEC Equalizer2Ptr* STDCALL Effect_Equalizer2_Create()
	{
		return new Equalizer2Ptr();
	}

	DECLSPEC void STDCALL Effect_Equalizer2_Delete(Equalizer2Ptr* ptr)
	{
		delete ptr;
	}

	DECLSPEC void STDCALL Effect_Equalizer2_Setup(Equalizer2Ptr* ptr, int sampleRate, int outputChannels, double lowFreq, double highFreq, double band1, double band2, double band3)
	{
		ptr->Update(sampleRate, outputChannels, lowFreq, highFreq, band1, band2, band3);
	}

	DECLSPEC void STDCALL Effect_Equalizer2_Process(
		Equalizer2Ptr* ptr, Equalizer2Data* data,
		double* wav_in_left, double* wav_in_right, double* wav_out_left, double* wav_out_right)
	{
		ptr->Process(data, wav_in_left, wav_in_right, wav_out_left, wav_out_right);
	}
}